home *** CD-ROM | disk | FTP | other *** search
- /*
-
- File: filesystem.c
- Author: Neil Cafferkey
- Copyright (C) 2001-2002 Neil Cafferkey
-
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston,
- MA 02111-1307, USA.
-
- */
-
-
- #include "handler_protos.h"
-
-
-
- /****i* ram.handler/CreateObject *******************************************
- *
- * NAME
- * CreateObject --
- *
- * SYNOPSIS
- * object = CreateObject(handler,name,type,
- * parent)
- *
- * struct Object *CreateObject(struct Handler *,TEXT *,BYTE,
- * struct Object *);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- struct Object *CreateObject(struct Handler *handler,const TEXT *name,
- BYTE type,struct Object *parent)
- {
- struct Object *object;
- LONG error;
- UPINT block_count;
-
- /* Check for an existing object with the same name */
-
- error=0;
- object=NULL;
- if(parent!=NULL)
- {
- parent=GetRealObject(parent);
- object=(APTR)FindNameNoCase((struct List *)&parent->elements,name);
- }
-
- /* Create a new object structure */
-
- if(object==NULL)
- {
- object=AllocMem(sizeof(struct Object),MEMF_CLEAR);
- if(object==NULL)
- error=ERROR_DISK_FULL;
-
- if(error==0)
- {
- block_count=MEMBLOCKS(sizeof(struct Object));
- object->block_count=MEMBLOCKS(sizeof(struct Object));
- handler->block_count+=MEMBLOCKS(sizeof(struct Object));
-
- NewList((struct List *)&object->elements);
- ((struct Node *)object)->ln_Pri=type;
- object->parent=parent;
- DateStamp(&object->date);
-
- if(name!=NULL)
- {
- name=FilePart(name);
- if(!SetName(handler,object,name))
- error=IoErr();
- }
-
- if(parent!=NULL)
- {
- AddTail((struct List *)&parent->elements,(struct Node *)object);
- CopyMem(&object->date,&parent->date,sizeof(struct DateStamp));
- }
- }
- }
- else
- {
- error=ERROR_OBJECT_EXISTS;
- }
-
- if(error==0)
- MatchNotifyRequests(handler);
-
- if(error!=0)
- {
- DeleteObject(handler,object);
- object=NULL;
- }
-
- /* Return the new object */
-
- SetIoErr(error);
- return object;
- }
-
-
-
- /****i* ram.handler/DeleteObject *******************************************
- *
- * NAME
- * DeleteObject --
- *
- * SYNOPSIS
- * success = DeleteObject(handler,object)
- *
- * BOOL DeleteObject(struct Handler *,struct Object *);
- *
- * FUNCTION
- *
- * INPUTS
- * object - the object to be deleted, or NULL for no action.
- *
- * RESULT
- * success - success indicator.
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- BOOL DeleteObject(struct Handler *handler,struct Object *object)
- {
- LONG error=0;
- BYTE object_type;
- struct Lock *lock;
- struct Block *block;
- struct MinNode *node;
- struct Object *real_object,*master_link,*heir,*dir;
- PINT block_diff;
-
- if(object!=NULL)
- {
- real_object=GetRealObject(object);
-
- /* Check for a non-empty, unlinked directory */
-
- object_type=((struct Node *)object)->ln_Pri;
- if((object_type==ST_USERDIR)&&(object->hard_link.mln_Succ==NULL)
- &&!IsListEmpty((struct List *)&object->elements))
- error=ERROR_DIRECTORY_NOT_EMPTY;
-
- /* Ensure the object isn't in use */
-
- lock=LockObject(handler,object,ACCESS_WRITE);
- if(lock==NULL)
- error=IoErr();
- CmdFreeLock(handler,lock);
-
- if(error==0)
- {
- /* Remove the object from its directory */
-
- if(object->parent!=NULL)
- Remove((struct Node *)object);
-
- /* Delete a hard link */
-
- if((object_type==ST_LINKFILE)||(object_type==ST_LINKDIR))
- {
- node=real_object->hard_link.mln_Succ;
- master_link=HARDLINK(node);
- Remove((APTR)&object->hard_link);
- if(object==master_link)
- {
- node=node->mln_Succ;
- if(node->mln_Succ!=NULL)
- {
- master_link=HARDLINK(node);
- while((node=(APTR)RemHead((APTR)&object->elements))!=NULL)
- AddTail((APTR)&master_link->elements,(APTR)node);
- }
- else
- {
- real_object->hard_link.mln_Succ=NULL;
- real_object->hard_link.mln_Pred=NULL;
- }
- }
- }
-
- /* Delete a linked object */
-
- else if((node=object->hard_link.mln_Succ)!=NULL)
- {
- master_link=HARDLINK(node);
- heir=HARDLINK(RemTail((APTR)&master_link->elements));
-
- /* Swap names and comments */
-
- block_diff=SwapStrings(&((struct Node *)heir)->ln_Name,
- &((struct Node *)object)->ln_Name);
- block_diff+=SwapStrings(&heir->comment,&object->comment);
- object->block_count+=block_diff;
- heir->block_count-=block_diff;
-
- /* Put object in its new directory */
-
- object->parent=heir->parent;
- AddTail((APTR)&object->parent->elements,(APTR)object);
-
- if(heir==master_link)
- {
- real_object->hard_link.mln_Succ=NULL;
- real_object->hard_link.mln_Pred=NULL;
- }
-
- /* Prepare to destroy "heir" link */
-
- Remove((APTR)heir);
- object=heir;
- }
-
- /* Delete the root directory and all other objects */
-
- else if(object_type==ST_ROOT)
- {
- dir=object;
-
- while(dir!=NULL)
- {
- object=(APTR)RemHead((struct List *)&dir->elements);
-
- if(object==NULL)
- {
- object=dir;
- dir=dir->parent;
- if(dir!=NULL)
- DeleteObject(handler,object);
- }
- else if(((struct Node *)object)->ln_Pri==ST_USERDIR)
- {
- dir=object;
- }
- else
- {
- DeleteObject(handler,object);
- }
- }
- }
-
- /* Delete an unlinked object */
-
- else
- {
- /* Remove all blocks if the object is a file */
-
- while((block=(APTR)RemTail((struct List *)&object->elements))
- !=NULL)
- FreeMem(block,sizeof(struct Block)+block->length);
- }
-
- /* Free object's memory */
-
- SetString(&((struct Node *)object)->ln_Name,NULL);
- SetString(&object->comment,NULL);
- handler->block_count-=object->block_count;
- FreeMem(object,sizeof(struct Object));
- }
- }
-
- /* Return result */
-
- SetIoErr(error);
- return error==0;
- }
-
-
-
- /****i* ram.handler/GetObject **********************************************
- *
- * NAME
- * GetObject --
- *
- * SYNOPSIS
- * object = GetObject(handler,lock,name,
- * parent)
- *
- * struct Object *GetObject(struct Handler *,struct Lock *,TEXT *,
- * struct Object **);
- *
- * FUNCTION
- *
- * INPUTS
- * lock - .
- * name - .
- * parent - .
- *
- * RESULT
- * object - The located object.
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- struct Object *GetObject(struct Handler *handler,
- struct Lock *lock,const TEXT *name,struct Object **parent)
- {
- const TEXT *p;
- TEXT ch,buffer[256];
- PINT pos;
- struct Object *object,*old_object;
-
- old_object=NULL;
- for(ch=*(p=name);(ch!=':')&&(ch!='\0');ch=*(++p));
- if(ch==':')
- name=p+1;
-
- /* Get object referenced by lock */
-
- lock=FixLock(handler,lock);
- object=(APTR)((struct FileLock *)lock)->fl_Key;
-
- /* Traverse textual portion of path */
-
- pos=0;
- while((pos!=-1)&&(object!=NULL))
- {
- pos=SplitName(name,'/',buffer,pos,256);
- if(*buffer!='\0')
- {
- old_object=object;
- if(((struct Node *)object)->ln_Pri>0)
- {
- object=GetRealObject(object);
- object=(struct Object *)
- FindNameNoCase((struct List *)&object->elements,buffer);
- }
- else
- {
- object=NULL;
- old_object=NULL;
- }
- }
- else if(pos!=-1)
- {
- object=object->parent;
- }
- }
-
- /* Record the parent directory of the supplied path, if it exists */
-
- if(parent!=NULL)
- {
- if(pos==-1)
- *parent=old_object;
- else
- *parent=NULL;
- }
-
- /* Return the located object */
-
- SetIoErr(ERROR_OBJECT_NOT_FOUND);
- return object;
- }
-
-
-
- /****i* ram.handler/ChangeFileSize *****************************************
- *
- * NAME
- * ChangeFileSize --
- *
- * SYNOPSIS
- * new_size = ChangeFileSize(handler,opening,offset,
- * mode)
- *
- * PINT ChangeFileSize(struct Handler *,struct Opening *,PINT,
- * LONG);
- *
- * FUNCTION
- * If there is not enough space for the requested size, the file size
- * will remain at its initial value and -1 will be returned.
- *
- *
- *
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- PINT ChangeFileSize(struct Handler *handler,struct Opening *opening,
- PINT offset,LONG mode)
- {
- PINT length,new_length,remainder,end_length,full_length;
- UPINT diff,old_pos,block_count;
- struct Block *block,*end_block;
- struct Object *file;
- LONG error=0;
-
- /* Get origin */
-
- file=opening->file;
-
- if(mode==OFFSET_BEGINNING)
- new_length=0;
- else if(mode==OFFSET_CURRENT)
- new_length=opening->pos;
- else
- new_length=file->length;
-
- if(-offset>new_length)
- {
- SetIoErr(ERROR_SEEK_ERROR);
- return -1;
- }
-
- new_length+=offset;
- length=file->length;
- block_count=file->block_count;
-
- old_pos=opening->pos;
-
- full_length=length;
- end_length=file->end_length;
- block=(struct Block *)file->elements.mlh_TailPred;
- if(end_length!=0)
- {
- full_length+=block->length-end_length;
- }
-
- if(new_length>length)
- {
- /* Add the required number of data bytes */
-
- remainder=new_length-full_length;
- end_length-=remainder;
-
- while(remainder>0)
- {
- block=AddDataBlock(handler,file,remainder);
- if(block!=NULL)
- {
- end_length=remainder;
- remainder-=block->length;
- }
- else
- remainder=0;
- }
-
- /* Remove new blocks upon failure */
-
- if(block==NULL)
- {
- new_length=-1;
- error=IoErr();
- ChangeFileSize(handler,opening,length,OFFSET_BEGINNING);
- }
- else
- file->end_length=end_length;
- }
- else if(length!=new_length)
- {
- /* Remove surplus blocks from the file */
-
- block=NULL;
- while(full_length>new_length)
- {
- FreeDataBlock(file,block);
- block=(APTR)RemTail((APTR)&file->elements);
- full_length-=block->length;
- }
- end_block=(APTR)file->elements.mlh_TailPred;
- if((APTR)end_block!=(APTR)&file->elements)
- end_length=end_block->length;
- else
- end_length=0;
- file->end_length=end_length;
-
- /* Allocate a suitably sized end block and copy old data to it */
-
- diff=new_length-full_length;
- file->length=full_length;
- CmdSeek(opening,0,OFFSET_END);
-
- if(ChangeFileSize(handler,opening,diff,OFFSET_END)!=-1)
- {
- WriteData(handler,opening,((UBYTE *)block)+sizeof(struct Block),
- diff);
- FreeDataBlock(file,block);
- }
- else
- AddTail((struct List *)&file->elements,(APTR)block);
-
- /* Ensure opening's position isn't past new EOF */
-
- if(opening->pos>new_length)
- {
- opening->block=(APTR)&file->elements.mlh_Tail;
- opening->block_pos=0;
- opening->pos=new_length;
- }
- }
-
- /* Re-establish old seek position */
-
- CmdSeek(opening,old_pos,OFFSET_BEGINNING);
-
- /* Store new file size */
-
- if(new_length!=-1)
- file->length=new_length;
- handler->block_count+=file->block_count-block_count;
-
- SetIoErr(error);
- return new_length;
- }
-
-
-
- /****i* ram.handler/ReadData ***********************************************
- *
- * NAME
- * ReadData --
- *
- * SYNOPSIS
- * read_length = ReadData(opening,buffer,length)
- *
- * UPINT ReadData(struct Opening *,UBYTE *,UPINT);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- UPINT ReadData(struct Opening *opening,UBYTE *buffer,UPINT length)
- {
- struct Block *block;
- UPINT block_pos,block_length,read_length=0,remainder;
- struct Object *file;
-
- /* Fill buffer until request has been fulfilled or EOF is reached */
-
- block=opening->block;
- block_pos=opening->block_pos;
- file=opening->file;
-
- remainder=file->length-opening->pos;
- if(length>remainder)
- length=remainder;
- remainder=length;
-
-
- #if 0
- ahead=file->length-opening->pos;
- if(length>ahead)
- length=ahead;
- length=remainder;
-
-
- if(opening->pos+length>file->length)
- length=file->length-opening->pos;
- remainder=length;
-
-
- if(opening->pos+length>file->length)
- length=file->length-opening->pos;
- remainder=length;
- #endif
-
- while(remainder>0)
- {
- /* Get number of remaining valid bytes in this block */
-
- block_length=GetBlockLength(file,block);
- block_length-=block_pos;
-
- /* Copy block contents into the caller's buffer */
-
- read_length=MIN(remainder,block_length);
- CopyMem(((UBYTE *)block)+sizeof(struct Block)+block_pos,buffer,
- read_length);
- remainder-=read_length;
- buffer+=read_length;
-
- /* Get next block */
-
- if(read_length==block_length)
- {
- block=(struct Block *)((struct MinNode *)block)->mln_Succ;
- block_pos=0;
- read_length=0;
- }
- }
-
- /* Record new position for next access */
-
- opening->block=block;
- opening->block_pos=block_pos+read_length;
- opening->pos+=length;
-
- /* Return number of bytes read */
-
- return length;
- }
-
-
-
- /****i* ram.handler/WriteData **********************************************
- *
- * NAME
- * WriteData --
- *
- * SYNOPSIS
- * write_length = WriteData(handler,opening,buffer,length)
- *
- * UPINT WriteData(struct Handler *,struct Opening *,UBYTE *,UPINT);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- UPINT WriteData(struct Handler *handler,struct Opening *opening,
- UBYTE *buffer,UPINT length)
- {
- struct Block *block,*end_block;
- struct Object *file;
- UPINT block_pos,block_length,write_length,remainder=length,block_count,
- file_length,pos;
- LONG error=0;
-
- file=opening->file;
- file_length=file->length;
- block_count=file->block_count;
- pos=opening->pos;
- block=opening->block;
- block_pos=opening->block_pos;
-
- /* If at EOF, go back to use up any space left in last block */
-
- if((pos==file_length)&&(pos!=0))
- {
- block=(struct Block *)((struct MinNode *)block)->mln_Pred;
- block_pos=file->end_length;
- }
-
- while((remainder>0)&&(block!=NULL)&&(error==0))
- {
- /* Add another block to the file if required */
-
- if(((struct MinNode *)block)->mln_Succ==NULL)
- {
- block=AddDataBlock(handler,opening->file,remainder);
- file->end_length=0;
- }
-
- /* Write as much as possible to the current block */
-
- if(block!=NULL)
- {
- block_length=block->length-block_pos;
- write_length=MIN(remainder,block_length);
- CopyMem(buffer,((UBYTE *)block)+sizeof(struct Block)+block_pos,
- write_length);
- remainder-=write_length;
- buffer+=write_length;
- block_pos+=write_length;
-
- /* Move on to next block if end of current block reached */
-
- if(write_length==block_length)
- {
- block=(struct Block *)((struct MinNode *)block)->mln_Succ;
- /* block_length=block->length;*/
- block_pos=0;
- }
- }
- else
- error=IoErr();
- }
-
- /* Recalculate length of used portion of last block */
-
- end_block=(struct Block *)file->elements.mlh_TailPred;
- if((block==end_block)&&(block_pos>file->end_length))
- {
- file->end_length=block_pos;
- block=(struct Block *)((struct MinNode *)block)->mln_Succ;
- block_pos=0;
- }
- else if((struct Block *)((struct MinNode *)block)->mln_Pred==end_block)
- file->end_length=end_block->length;
-
- /* Update file size, volume size and current position */
-
- length-=remainder;
- pos+=length;
- if(pos>file_length)
- file->length=pos;
- opening->pos=pos;
- opening->block=block;
- opening->block_pos=block_pos;
- handler->block_count+=file->block_count-block_count;
-
- /* Return number of bytes written */
-
- SetIoErr(error);
- return length;
- }
-
-
- #if 0
- UPINT WriteData(struct Handler *handler,struct Opening *opening,
- UBYTE *buffer,UPINT length)
- {
- struct Block *block,*end_block;
- struct Object *file;
- UPINT block_pos,block_length,write_length,remainder=length,file_length,
- block_count,pos;
- LONG error=0;
-
- file=opening->file;
- block_count=file->block_count;
- file_length=file->length;
- block=opening->block;
- block_pos=opening->block_pos;
-
- while((remainder>0)&&(block!=NULL))
- {
- /* Add another block to the file if required */
-
- if(((struct MinNode *)block)->mln_Succ==NULL)
- {
- block=AddDataBlock(handler,opening->file,remainder);
- file->end_length=0;
- }
-
- /* Write as much as possible to the current block */
-
- if(block!=NULL)
- {
- block_length=block->length-block_pos;
- write_length=MIN(remainder,block_length);
- CopyMem(buffer,((UBYTE *)block)+sizeof(struct Block)+block_pos,
- write_length);
- remainder-=write_length;
- buffer+=write_length;
- block_pos+=write_length;
-
- /* Move on to next block if end of current block has been reached */
-
- if(write_length==block_length)
- {
- block=(struct Block *)((struct MinNode *)block)->mln_Succ;
- block_length=block->length;
- block_pos=0;
- }
- }
- else
- error=IoErr();
- }
-
- /* Recalculate length of used portion of last block */
-
- end_block=(struct Block *)file->elements.mlh_TailPred;
- if((block==end_block)&&(block_pos>file->end_length))
- file->end_length=block_pos;
- if((struct Block *)((struct MinNode *)block)->mln_Pred==end_block)
- file->end_length=end_block->length;
-
- /* Update file size, volume size and current position */
-
- pos=opening->pos;
- length-=remainder;
- pos+=length;
- if(pos>file_length)
- file->length=pos;
- opening->pos=pos;
- opening->block=block;
- opening->block_pos=block_pos;
- handler->block_count+=file->block_count-block_count;
-
- /* Return number of bytes written */
-
- SetIoErr(error);
- return length;
- }
- #endif
-
-
- /****i* ram.handler/LockObject *********************************************
- *
- * NAME
- * LockObject --
- *
- * SYNOPSIS
- * lock = LockObject(handler,object,
- * access)
- *
- * struct Lock *LockObject(struct Handler *handler,struct Object *,
- * LONG);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- struct Lock *LockObject(struct Handler *handler,struct Object *object,
- LONG access)
- {
- struct Lock *lock;
- LONG error,lock_access;
-
- object=GetRealObject(object);
- lock=object->lock;
-
- if(lock==NULL)
- {
- lock=AllocMem(sizeof(struct Lock),MEMF_PUBLIC|MEMF_CLEAR);
-
- if(lock!=NULL)
- {
- object->lock=lock;
-
- ((struct FileLock *)lock)->fl_Key=(PINT)object;
- ((struct FileLock *)lock)->fl_Access=access;
- ((struct FileLock *)lock)->fl_Task=handler->proc_port;
- ((struct FileLock *)lock)->fl_Volume=MKBADDR(handler->volume);
- }
- else
- error=IoErr();
- }
- /*#ifndef AMIGAOS*/
- else
- {
- lock_access=((struct FileLock *)lock)->fl_Access;
- if((access==ACCESS_WRITE)||(lock_access==ACCESS_WRITE))
- {
- lock=NULL;
- error=ERROR_OBJECT_IN_USE;
- }
- }
- /*#endif*/
-
- if(lock!=NULL)
- {
- lock->lock_count++;
- handler->lock_count++;
- }
-
- SetIoErr(error);
-
- return lock;
- }
-
-
-
- /****i* ram.handler/ExamineObject ******************************************
- *
- * NAME
- * ExamineObject --
- *
- * SYNOPSIS
- * success = ExamineObject(handler,object,
- * info)
- *
- * BOOL ExamineObject(struct Handler *,struct Object *,
- * struct FileInfoBlock *);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- BOOL ExamineObject(struct Handler *handler,struct Object *object,
- struct FileInfoBlock *info)
- {
- BOOL success;
- struct Object *next_object;
- STRPTR s;
- LONG entry_type;
-
- if(object==NULL)
- {
- object=(struct Object *)info->fib_DiskKey;
- next_object=(APTR)((struct Node *)object)->ln_Succ;
- }
- else
- next_object=(APTR)object->elements.mlh_Head;
-
- if(next_object!=NULL)
- {
- /* Fill in information from object */
-
- entry_type=((struct Node *)object)->ln_Pri;
- info->fib_DirEntryType=entry_type;
- info->fib_EntryType=entry_type;
- s=((struct Node *)object)->ln_Name;
- CopyMem(MkBStr(s),&info->fib_FileName,StrSize(s));
- s=object->comment;
- if(s!=NULL)
- CopyMem(MkBStr(s),&info->fib_Comment,StrLen(s)+1);
- else
- info->fib_Comment[0]='\0';
- info->fib_NumBlocks=object->block_count;
-
- /* Fill in information from real object */
-
- object=GetRealObject(object);
-
- info->fib_Protection=object->protection;
- info->fib_Size=object->length;
- CopyMem(&object->date,&info->fib_Date,sizeof(struct DateStamp));
-
- /* Prepare for next examination */
-
- success=TRUE;
- info->fib_DiskKey=(PINT)next_object;
- }
- else
- {
- success=FALSE;
- SetIoErr(ERROR_NO_MORE_ENTRIES);
- }
-
- return success;
- }
-
-
-
- /****i* ram.handler/SetName ************************************************
- *
- * NAME
- * SetName --
- *
- * SYNOPSIS
- * success = SetName(handler,object,name)
- *
- * BOOL SetName(struct Handler *,struct Object *,TEXT *);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- BOOL SetName(struct Handler *handler,struct Object *object,
- const TEXT *name)
- {
- LONG error;
- const TEXT *p;
- TEXT ch;
- struct Locale *locale;
- PINT block_diff;
-
- error=0;
-
- /* Check name isn't too long */
-
- if(StrSize(name)>sizeof(((struct FileInfoBlock *)NULL)->fib_FileName))
- error=ERROR_INVALID_COMPONENT_NAME;
-
- /* Check name doesn't have any strange characters in it */
-
- locale=handler->locale;
- for(p=name;(ch=*p)!='\0';p++)
- if(!IsPrint(locale,ch)||IsCntrl(locale,ch)||(ch==':'))
- error=ERROR_INVALID_COMPONENT_NAME;
-
- /* Store new name */
-
- if(error==0)
- {
- block_diff=SetString(&((struct Node *)object)->ln_Name,name);
- if(block_diff==-1)
- error=IoErr();
- else
- {
- object->block_count+=block_diff;
- handler->block_count+=block_diff;
- }
- }
-
- /* Return success indicator */
-
- SetIoErr(error);
- return error==0;
- }
-
-
-
- /****i* ram.handler/FixLock ************************************************
- *
- * NAME
- * FixLock --
- *
- * SYNOPSIS
- * fixed_lock = FixLock(handler,lock)
- *
- * struct Lock *FixLock(struct Handler *,struct Lock *);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- struct Lock *FixLock(struct Handler *handler,struct Lock *lock)
- {
- if(lock==NULL)
- lock=handler->root_dir->lock;
-
- return lock;
- }
-
-
-
- /****i* ram.handler/AddDataBlock *******************************************
- *
- * NAME
- * AddDataBlock --
- *
- * SYNOPSIS
- * block = AddDataBlock(file,length)
- *
- * struct Block *AddDataBlock(struct Object *,UPINT);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- * Attempts to allocate a smaller block if the requested size cannot be
- * obtained.
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- struct Block *AddDataBlock(struct Handler *handler,struct Object *file,
- UPINT length)
- {
- struct Block *block;
- UPINT alloc_size;
- ULONG limit;
-
- /* Ensure block size is within limits */
-
- alloc_size=sizeof(struct Block)+length;
-
- limit=handler->max_block_size;
- if(alloc_size>limit)
- alloc_size=limit;
-
- limit=handler->min_block_size;
- if(alloc_size<limit)
- alloc_size=limit;
-
- /* Allocate a multiple of the memory block size */
-
- block=NULL;
- while((block==NULL)&&(alloc_size>=limit))
- {
- alloc_size=((alloc_size-1)&(~MEM_BLOCKMASK))+MEM_BLOCKSIZE;
- block=AllocMem(alloc_size,MEMF_ANY);
- if(block==NULL)
- alloc_size>>=1;
- }
-
- /* Add the block to the end of the file */
-
- if(block!=NULL)
- {
- AddTail((struct List *)&file->elements,(struct Node *)block);
- block->length=alloc_size-sizeof(struct Block);
- file->block_count+=alloc_size>>MEM_BLOCKSHIFT;
- }
- else
- SetIoErr(ERROR_DISK_FULL);
-
- /* Return the new block */
-
- return block;
- }
-
-
-
- /****i* ram.handler/FreeDataBlock ******************************************
- *
- * NAME
- * FreeDataBlock --
- *
- * SYNOPSIS
- * FreeDataBlock(file,block)
- *
- * VOID FreeDataBlock(struct Object *,struct Block *);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- VOID FreeDataBlock(struct Object *file,struct Block *block)
- {
- UPINT alloc_size;
-
- if(block!=NULL)
- {
- alloc_size=sizeof(struct Block)+block->length;
- file->block_count-=alloc_size>>MEM_BLOCKSHIFT;
- FreeMem(block,alloc_size);
- }
-
- return;
- }
-
-
-
- /****i* ram.handler/GetRealObject ******************************************
- *
- * NAME
- * GetRealObject --
- *
- * SYNOPSIS
- * real_object = GetRealObject(object)
- *
- * struct Object *GetRealObject(struct Object *);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- struct Object *GetRealObject(struct Object *object)
- {
- struct MinNode *node,*pred;
-
- /* Get first node in list */
-
- node=&object->hard_link;
- if(node->mln_Pred!=NULL)
- {
- while((pred=node->mln_Pred)!=NULL)
- node=pred;
- node=node->mln_Succ;
- }
-
- /* Get object from node address */
-
- object=HARDLINK(node);
- return object;
- }
-
-
-
- /****i* ram.handler/GetRealObject ******************************************
- *
- * NAME
- * GetBlockLength --
- *
- * SYNOPSIS
- * length = GetBlockLength(file,block)
- *
- * UPINT GetBlockLength(struct Object *,struct Block *);
- *
- * FUNCTION
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- *
- * BUGS
- *
- * SEE ALSO
- *
- ****************************************************************************
- *
- */
-
- UPINT GetBlockLength(struct Object *file,struct Block *block)
- {
- UPINT length;
-
- if(block==(APTR)file->elements.mlh_TailPred)
- length=file->end_length;
- else if(((struct MinNode *)block)->mln_Succ==NULL)
- length=0;
- else
- length=block->length;
-
- return length;
- }
-
-
-
-